﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using Microsoft.Practices.CompositeUI;
using System.Reflection;
using PictureManager.Core;
using PictureManager.Constant;

namespace PictureManager.Controls
{

    public partial class BaseForm : DockContent
    {
        protected bool IsLoaded;
      
        private WorkItem workItem;
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        [ServiceDependency]
        public WorkItem WorkItem
        {
            get { return workItem; }
            set { workItem = value; }
        }

        public BaseForm()
        {
            InitializeComponent();

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            InitEvent();
            InitData();
        }

        public virtual void InitEvent()
        {
        }

        public virtual void InitData()
        {
        }

        #region WorkItem Items Methods
        protected void SetItemKeyValue(string key, object value)
        {
            if (WorkItem.Items.Contains(key)) WorkItem.Items.Remove(WorkItem.Items[key]);
            if (value != null) WorkItem.Items.Add(value, key);
        }

        protected bool HasItemKeyValue(string key)
        {
            return WorkItem.Items.Contains(key);
        }

        protected object GetItemKeyValue(string key)
        {
            return WorkItem.Items[key];
        }
        #endregion

        #region Show Windows
        protected TypeName ShowFloatWindow<TypeName>() where TypeName : DockContent
        {
            return ShowFloatWindow<TypeName>("");
        }

        protected TypeName ShowFloatWindow<TypeName>(string caption) where TypeName : DockContent
        {
            return ShowFloatWindow<TypeName>(caption, Guid.NewGuid().ToString());
        }

        protected TypeName ShowFloatWindow<TypeName>(string caption, string workItemName) where TypeName : DockContent
        {
            TypeName smartPart = WorkItem.Items.AddNew<TypeName>(workItemName);
            if (!String.IsNullOrEmpty(caption)) smartPart.Text = caption;

            if (smartPart != null)
            {
                DockPanel dockPanel = this.WorkItem.RootWorkItem.Items.Get<DockPanel>(Constants.DockPanel);

                //Restore layout
                int _left = 0, _top = 0, _height = 0, _width = 0;

                if (ConfigurationManager.Instance.CustomizedLayoutTable.ContainsKey(typeof(TypeName).ToString() + "_Left"))
                    Int32.TryParse(ConfigurationManager.Instance.CustomizedLayoutTable[typeof(TypeName).ToString() + "_Left"].ToString(), out _left);

                if (ConfigurationManager.Instance.CustomizedLayoutTable.ContainsKey(typeof(TypeName).ToString() + "_Top"))
                    Int32.TryParse(ConfigurationManager.Instance.CustomizedLayoutTable[typeof(TypeName).ToString() + "_Top"].ToString(), out _top);

                if (ConfigurationManager.Instance.CustomizedLayoutTable.ContainsKey(typeof(TypeName).ToString() + "_Height"))
                    Int32.TryParse(ConfigurationManager.Instance.CustomizedLayoutTable[typeof(TypeName).ToString() + "_Height"].ToString(), out _height);

                if (ConfigurationManager.Instance.CustomizedLayoutTable.ContainsKey(typeof(TypeName).ToString() + "_Width"))
                    Int32.TryParse(ConfigurationManager.Instance.CustomizedLayoutTable[typeof(TypeName).ToString() + "_Width"].ToString(), out _width);

                if (_left * _top * _height * _width == 0)
                {
                    smartPart.Show(dockPanel, DockState.Float);
                }
                else
                {
                    smartPart.Show(dockPanel, new Rectangle(_left, _top, _width, _height));
                }
            }

            return smartPart;
        }

        /// <summary>
        /// Show control in exist float window by tabkey, 
        /// if the tabkey isn't exist then show as usual, and add the tabkey to workitem for next show.
        /// By Default,the tab page disable end-user docking.
        /// </summary>
        /// <typeparam name="TypeName"></typeparam>
        /// <param name="caption"></param>
        /// <param name="tabKey"></param>
        /// <returns></returns>
        protected TypeName ShowFloatWindowWithTab<TypeName>(string caption, string tabKey) where TypeName : DockContent
        {
            return ShowFloatWindowWithTab<TypeName>(caption, tabKey, false);
        }

        protected TypeName ShowFloatWindowWithTab<TypeName>(string caption, string tabKey, bool allowEndUserDocking) where TypeName : DockContent
        {
            return ShowFloatWindowWithTab<TypeName>(caption, Guid.NewGuid().ToString(), tabKey, allowEndUserDocking);
        }

        protected TypeName ShowFloatWindowWithTab<TypeName>(string caption, string workItemName, string tabKey) where TypeName : DockContent
        {
            return ShowFloatWindowWithTab<TypeName>(caption, workItemName, tabKey, false);
        }

        protected TypeName ShowFloatWindowWithTab<TypeName>(string caption, string workItemName, string tabKey, bool allowEndUserDocking) where TypeName : DockContent
        {
            TypeName smartPart = null;
            bool isShow = false;
            if (WorkItem.Items.Contains(tabKey) && WorkItem.Items[tabKey] != null)
            {
                DockPane pane = WorkItem.Items[tabKey] as DockPane;

                if (pane != null && pane.Contents.Count != 0)
                {
                    smartPart = WorkItem.Items.AddNew<TypeName>(workItemName);
                    if (!String.IsNullOrEmpty(caption)) smartPart.Text = caption;

                    if (smartPart != null)
                    {
                        if (!allowEndUserDocking)
                        {
                            SetDockContentUserDocking(smartPart, false);
                        }
                        smartPart.Show(pane.DockPanel, DockState.Float);
                        smartPart.Pane.DockTo(pane, DockStyle.Fill, -1);
                        if (pane.Contents.Count == 2)
                        {
                            pane.TopLevelControl.Height += 21;
                        }
                        isShow = true;
                    }
                }
            }
            if (!isShow)
            {
                smartPart = ShowFloatWindow<TypeName>(caption, workItemName);
                if (!allowEndUserDocking)
                {
                    SetDockContentUserDocking(smartPart, false);
                    SetFloatWindowUserDocking(smartPart, false);
                }
                DockPane pane = smartPart.Pane;
               
                WorkItem.Items.Remove(WorkItem.Items[tabKey]);
                if (pane != null )
                {
                    WorkItem.Items.Add(pane, tabKey);
                }
            }
            return smartPart;
        }
        /// <summary>
        /// set indication to disable end-user docking, so that the dockpaneStrip OnMouseDown event can't fire BeginDrag function
        /// set indication to dispose when close the smartPart.
        /// </summary>
        /// <param name="smartPart"></param>
        /// <param name="allowEndUserDocking"></param>
        protected void SetDockContentUserDocking(DockContent smartPart, bool allowEndUserDocking)
        {
            if (smartPart != null)
            {
                smartPart.DockHandler.AllowEndUserDocking = allowEndUserDocking;
                smartPart.DockHandler.HideOnClose = false;
            }
        }
        /// <summary>
        /// set top float window indication to disable end-user docking
        /// </summary>
        /// <param name="smartPart"></param>
        /// <param name="allowEndUserDocking"></param>
        protected void SetFloatWindowUserDocking(Control smartPart, bool allowEndUserDocking)
        {
            while (smartPart != null && !(smartPart is WeifenLuo.WinFormsUI.Docking.FloatWindow))
            {
                smartPart = smartPart.Parent;
            }
            if (smartPart != null && smartPart is WeifenLuo.WinFormsUI.Docking.FloatWindow)
            {
                ((WeifenLuo.WinFormsUI.Docking.FloatWindow)smartPart).AllowEndUserDocking = allowEndUserDocking;
            }
        }
        #endregion
    }
}
